package de.lmu.mvs.lerngruppenfinder.interests;

import java.util.ArrayList;
import java.util.List;

import android.util.Log;

import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonValue;

import de.lmu.mvs.lerngruppenfinder.utils.Constants;

/**
 * InterestTree holds all interests in a parent children relationship.
 * The three is build from a JsonArray that contains all interests.
 * 
 * Interests can easily be found by either id or its name
 * 
 * @author Christopher Gebhardt
 * @date 24.06.2014
 *
 */
public class InterestTree {

	private static final String TAG = InterestTree.class.getSimpleName();

	public InterestNode root = null;

	public InterestTree(InterestNode rootNode){
		if(rootNode != null){
			root = rootNode;
		} else {
			throw new IllegalArgumentException("Root node must not be null");
		}
	}

	public InterestTree(JsonArray json) throws IllegalArgumentException {
		if(buildTree(json)){
			Log.i(TAG, "Interest tree successfully build.");
		} else {
			throw new IllegalArgumentException("JsonArray could not be parsed");
		}
	}

	public InterestTree(JsonArray jsonInterests, JsonArray jsonUserInterests) throws IllegalArgumentException {
		if(buildTree(jsonInterests)){
			setUserInterests(jsonUserInterests);
			Log.i(TAG, "Interest tree successfully build.");
		} else {
			throw new IllegalArgumentException("JsonArray could not be parsed");
		}
	}

	private boolean buildTree(JsonArray json) {
		root = new InterestNode(0, "root");

		try {
			for (JsonValue jsonValue : json) {
				if(jsonValue.isObject()){
					String idStr = jsonValue.asObject().get("id").asString();
					String name = jsonValue.asObject().get("name").asString();
					String parentIdStr = jsonValue.asObject().get("superFachgebiet").asString();

					InterestNode parent = find(Integer.parseInt(parentIdStr));
					if(parent != null){
						parent.addChildren(new InterestNode(Integer.parseInt(idStr), name).setParent(parent));
					}
				}
			}
			return true;
		} catch (com.eclipsesource.json.ParseException e) {
			// String could not be parsed to json
			Log.e(TAG, e.getLocalizedMessage());
			return false;
		} catch (UnsupportedOperationException e){
			// String could not be parsed to JsonObject
			Log.e(TAG, e.getLocalizedMessage());
			return false;
		}
	}
	
	private void setUserInterests(JsonArray userInterests){
		try {
			for (JsonValue jsonValue : userInterests) {
				if(jsonValue.isObject()){
					int id = Integer.parseInt(jsonValue.asObject().get(Constants.JSON_INTEREST_ID).asString());

					InterestNode node;
					if((node = root.find(id)) != null){
						node.belongsToUser = true;
					}
				}
			}
		} catch (com.eclipsesource.json.ParseException e) {
			// String could not be parsed to json
			Log.e(TAG, e.getLocalizedMessage());
		} catch (UnsupportedOperationException e){
			// String could not be parsed to JsonObject
			Log.e(TAG, e.getLocalizedMessage());
		}
	}

	public InterestNode find(int id){
		if(root != null){
			return root.find(id);
		} else {
			return null;
		}
	}

	public InterestNode find(String name){
		if(root != null){
			return root.find(name);
		} else {
			return null;
		}
	}

	public List<String> getChildrenNames(int level) {
		ArrayList<String> children = new ArrayList<String>();

		for (InterestNode node : find(level).getChildren()) {
			children.add(node.getInterestName());	
		}
		return children;
	}

	/**
	 * @return a list with all interest ids in this tree
	 */
	public List<Integer> getAllInterests(){
		List<Integer> interests = root.getAllInterests();
		return interests;
	}
}
